package com.cbwl.eoas.cms.web.controller.security;

import java.util.Set;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AccountException;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.SimplePrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.cbwl.eoas.cms.api.sysconfig.ISysResourceService;
import com.cbwl.eoas.cms.api.sysconfig.ISysUserService;
import com.cbwl.eoas.cms.model.sysconfig.SysResourceDTO;
import com.cbwl.eoas.cms.model.sysconfig.SysUserDTO;
import com.cbwl.eoas.common.framework.session.SecurityUserDTO;
import com.cbwl.eoas.common.framework.session.SessionManager;

public class MonitorRealm extends AuthorizingRealm {

	
	
	private static Logger logger = LoggerFactory.getLogger(MonitorRealm.class);
	
	//业务层注解
	@Autowired
	private ISysUserService sysUserService;
	
	@Autowired
	private ISysResourceService sysResourceService;
	
	/**
	 * 验证
	 */
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException {
		
		UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
		String username = token.getUsername();
		logger.info("开始用户认证{}",username);
		if (username == null) {
			throw new AccountException("登录名不允许为空!");
		}
		 SysUserDTO sysuser = new SysUserDTO();
		 sysuser.setUserLoginname(username);
		 sysuser = sysUserService.getUserDTOByParam(sysuser);
		 //认证用户
		 SimpleAuthenticationInfo saInfo = new SimpleAuthenticationInfo(username, sysuser.getUserPassword(), getName());
		 
		 //认证成功后，查询出相应的用户信息
		 SecurityUserDTO suser = sysUserService.getSecurityUserByLoginName(sysuser);
		 SysResourceDTO bean = new SysResourceDTO();
	     bean.setUid(sysuser.getId());
		 Set<String> permissions = sysResourceService.queryMenuForAuth(bean);
		 suser.setMenus(permissions);
		 SessionManager.setAttribute("securityUser", suser);

         clearCache(saInfo.getPrincipals());
		 
         logger.info("认证结束,用户名和密码正确{}",username);
         
		 return saInfo;
	}

	/**
	 * 授权
	 */
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
		
		SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
		//判断是否登录
	    if (!SessionManager.isAuthenticated()) {
            return null;
        }
	    
        if (!SecurityUtils.getSubject().isAuthenticated()) {
            doClearCache(principalCollection);
            SecurityUtils.getSubject().logout();
            return null;
        }
        
		//设置用户的所有角色
//	    authorizationInfo.setRoles(null);
	    
        String username = (String) principalCollection.getPrimaryPrincipal();
        logger.info("用户登入成功后，开始授权操作{}",username);
        SysUserDTO sysuser = new SysUserDTO();
		sysuser.setUserLoginname(username);
		sysuser = sysUserService.getUserDTOByParam(sysuser);
	    if(sysuser != null){
	    	SysResourceDTO bean = new SysResourceDTO();
	    	bean.setUid(sysuser.getId());
	    	  Set<String> permissions = sysResourceService.queryMenuForAuth(bean);
	            if (permissions != null && permissions.size() > 0) {
	            	permissions.forEach(e ->{
	            		 authorizationInfo.addStringPermission(e);
	            	});
	            }
	            logger.info("用户授权操作结束{}",username);
	            return authorizationInfo;
	        } else {
	            throw new AuthorizationException();
	    }
	}

	/**
	 * 更新用户授权信息缓存.
	 */
	public void clearCachedAuthorizationInfo(String principal) {
		SimplePrincipalCollection principals = new SimplePrincipalCollection(principal, getName());
		clearCachedAuthorizationInfo(principals);
	}

	/**
	* 清除所有用户授权信息缓存.
	*/
	public void clearAllCachedAuthorizationInfo() {
		Cache<Object, AuthorizationInfo> cache = getAuthorizationCache();
		if (cache != null) {
			for (Object key : cache.keys()) {
				cache.remove(key);
			}
		}
	}

	/**  
	 * 将一些数据放到ShiroSession中,以便于其它地方使用  
	 *
	 *
	 ** @see 比如Controller,使用时直接用HttpSession.getAttribute(key)就可以取到  
	*/

	private void setSession(Object key, Object value) {
		Subject currentUser = SecurityUtils.getSubject();
		if (null != currentUser) {
			Session session = currentUser.getSession();
			// System.out.println("Session默认超时时间为[" + session.getTimeout() + "]毫秒");
			if (null != session) {
				session.setAttribute(key, value);
			}
		}

	}

}